<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />

<link href="css/screen.css" media="all" rel="stylesheet" type="text/css">

<link href='http://fonts.googleapis.com/css?family=Droid+Sans&v1' rel='stylesheet' type='text/css'>

<link type="text/css" href="css/jquery.jscrollpane.css" rel="stylesheet" media="all" />
<link type="text/css" href="css/jquery.jscrollpane.custom.css" rel="stylesheet" media="all" />

<link type="text/css" rel="stylesheet" href="css/shCoreDefault.css"/>
<link type="text/css" rel="stylesheet" href="css/shThemeRDark.css"/>
</head>
<body>
<div id="header">
  <div class="headline"><img src="img/slogan.png" alt="" /></div>
  <div id="navigation">
    <ul>
      <li><a href="#" class="active link-0">
        <div class="icon"></div>
        <p>Start<br />presentation</p>
        </a></li>
      <li><a href="#" class="link-1">
        <div class="icon"></div>
        <p>Create<br />background</p>
        </a></li>
      <li><a href="#" class="link-2">
        <div class="icon"></div>
        <p>Assign<br />background</p>
        </a></li>
      <li><a href="#" class="link-3">
        <div class="icon"></div>
        <p>Integrate<br />controls</p>
        </a></li>
      <li><a href="#" class="link-4">
        <div class="icon"></div>
        <p>Markers<br />and overlays</p>
        </a></li>
      <li><a href="#" class="link-5">
        <div class="icon"></div>
        <p>Styled<br />windows</p>
        </a></li>
    </ul>
  </div>
</div>
<div id="debug" style="display: none;"> <a href="#" class="nn">N++</a>&nbsp; <a href="#"  class="n">N</a>&nbsp; <a href="#"  class="s">S</a>&nbsp; <a href="#"  class="ss">S++</a>&nbsp;||&nbsp; <a href="#"  class="ww">W++</a>&nbsp; <a href="#"  class="w">W</a>&nbsp; <a href="#"  class="e">E</a>&nbsp; <a href="#"  class="ee">E++</a>
  <p class="coordinates"></p>
  <p class="mouse"></p>
</div>
<div id="map_canvas" style="width:100%; height:100%;"></div>
<div id="content">
  <div id="content-1" class="content">
    <ul class="headlines">
      <li class="summary"><a href="#">Summary</a></li>
      <li><a href="#">About<br />
        the file</a></li>
      <li><a href="#">Tile background<br />
        with MapTiler</a></li>
      <li><a href="#">Tip: Varying<br />
        backgrounds</a></li>
    </ul>
    <div class="section summary">
      <ul>
        <li>MapTiler creates tiles for all zoom levels</li>
      	<li>Image dimensions have to be multiple of 256</li>
      	<li>Zoom levels go from 0 to 19</li>
        <li>To get a different look on each zoom level, render selective levels from several images</li>
      	<li>8192 x 4096 px will result in 5 (1-5) usable zoom levels
      	  <br />(level 0 is not usable, it's simply too small)
        </li>
      </ul>
    </div>
    <div class="section">
      <p>Before you create a background there are some facts about  Google Maps you should know:</p>
      <ul>
        <li>In Google Maps zoom level 0 is completely zoomed  out and 19 zoomed in</li>
        <li>Default tile size in Google Maps is 256 x 256  and MapTiler will automatically output that, so make sure the resolution is a  multiple of 256</li>
        <li>8192 x 4096 px will get you 6 zoom levels, but  zoom levels 0 and 1 are usually too small so effectively it&rsquo;s more like 4-5</li>
        <li>In that case I suggest to allow a zoom range  from 1 to 5 and set 2 as default</li>
      </ul>
    </div>
    <div class="section">
      <p>The easiest way to get tiles from your file is the tool  MapTiler. It is still in beta but for this task it is more than enough.</p>
      <ul>
        <li>Get MapTiler from <a href="http://maptiler.org">http://maptiler.org</a></li>
        <li>In MapTiler choose &ldquo;Image Based Tiles (Raster)&rdquo;</li>
        <li>Add your background image</li>
        <li>Since we&rsquo;re not working with maps here you can  ignore the following step</li>
        <li>Render all zoom levels or choose the ones the  background is used for (that&rsquo;s how you can have different backgrounds on  different zoom levels) then choose a file format</li>
        <li>Choose your destination folder</li>
        <li>Continue clicking continue until the rendering  starts</li>
      </ul>
    </div>
    <div class="section">
      <ul>
        <li>Create multiple backgrounds for different zoom  levels and export them in full size</li>
        <li>In MapTiler export the zoom levels you want from  each background as described before</li>
      </ul>
    </div>
  </div>
  <div id="content-2" class="content">
    <ul class="headlines">
      <li class="summary"><a href="#">Summary</a></li>
      <li><a href="#">Import  Google<br>
      Maps API</a></li>
      <li><a href="#">Create own <br>
      ImageMapType</a></li>
      <li><a href="#">Tip: How to get <br>
      LatLng coordinations</a></li>
    </ul>
    <div class="section summary">
      <ul>
        <li>Implement Google Maps API</li>
        <li>Version 3 of the API requires no API key</li>
        <li>jQuery can do the initialization and it also simplifies other tasks</li>
        <li>Create a map type (like satellite or map) that loads custom images</li>
        <li>Repetition in x- and y-direction can be turned on and off</li>
      </ul>
    </div>
    <div class="section">
      <ul>
        <li>Version  3 of the API requires no API key.</li>
        <li>jQuery  can be easily combined with the GMaps API in order to simplify code and add  functions</li>
        <li>The parameter &ldquo;sensor&rdquo; has to be defined as true  or false, it defines if a sensor is used to determine the location of the user  (unnecessary in this case therefore it&rsquo;s set to false).</li>
        <li>I used Version 3.3 instead of 3.4 because it  caused an error in Chrome if the resolution of the background wasn&rsquo;t square and  therefore missing tiles in regions that didn&rsquo;t matter. Making the background  square makes the output even smaller so the resolution must be bigger. My memory  couldn&rsquo;t handle a bigger file size so I left it at that.</li>
      </ul>
      <pre class="brush: xml"> &lt;script type=&quot;text/javascript&quot; 
      	src=&quot;http://maps.google.com/maps/api/js ?v=3.3&amp;sensor=false&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;js/jquery-1.6.2.min.js&quot;&gt;&lt;/script&gt;</pre>
      <p>This div-element will contain the map.</p>
      <pre class="brush: xml">
        <div id="map_canvas" style="width:100%; height:100%"></div>
      </pre>
      <ul>
        <li>Set map canvas, zoom and startcenter</li>
        <li>Adjust the background color to your background,  because otherwise the areas &ldquo;north&rdquo; and &ldquo;south&rdquo; of your background will be  Google Maps&rsquo; default grey</li>
        <li>Add the map type &ldquo;demo&rdquo; while removing the  defaults</li>
        <li>Hide the map type &amp; street view controls</li>
        <li>Position the pan &amp; zoom controls to the left  center</li>
        <li>Initialize with jQuery</li>
      </ul>
      <pre class="brush: js">
      	// Set global variables
        var map, startCenter;
        (function ($) {
          function mapInit() {
          // Setting container for map
          var mapCanvas = $("#map_canvas")[0];
          
          // Creating an option object for the map  
          mapOptions = {
            zoom: 2, 
            center: startCenter,
            backgroundColor: '#000000',
        
            mapTypeControlOptions: {    
              // Removing all usual map types from list
              mapTypeIds: "demo"
            },
            mapTypeControl: false,      // Hiding the map type control
            streetViewControl: false,   // Hiding the StreetView control
            
            // Positioning the controls 
            panControlOptions: {
              position: google.maps.ControlPosition.LEFT_CENTER
            },
            zoomControlOptions: {
              position: google.maps.ControlPosition.LEFT_CENTER
            }     
          };
          
          // Initializing the map  
          map = new google.maps.Map(mapCanvas, mapOptions);
        }  $(document).ready(function () {
            // coordinates for center of the map (more or less)
            startCenter = new google.maps.LatLng(-60.864, -18.652);  
            mapInit(); 
        });
        })(jQuery);
      </pre>
    </div>
    <div class="section">
      <ul>
        <li>Add a function (&lsquo;mapTypeInit&rsquo;) to create your  mapType</li>
        <li>&lsquo;tileSize&rsquo; has to be set</li>
        <li>Set &lsquo;isPng&rsquo; according to your choice in MapTiler  earlier</li>
        <li>The function &lsquo;mapTypeInit&rsquo; also needs the  functions &lsquo;mapTypeGetTileUrl&rsquo; and &lsquo;mapTypeGetNormalizedCoord&rsquo; to generate the  correct background paths</li>
        <li>If you want to change the repetition of the  background on the x &amp; y axes take a look on the &lsquo;mapTypeGetNormalizedCoord&rsquo;  function, but I don&rsquo;t recommend removing the x-repetition because the &lsquo;panTo&rsquo;  command moves the map to the nearest occurrence of the position, which could be  left or right from your main map (like Google Maps/Earth would move from Canada  to Japan westwards and not the whole way eastwards)</li>
      </ul>
      <pre class="brush: js">
      /**
       *  Initializes the ImageMapType
       */
      function mapTypeInit() {
        // Creating an option object for the ImageMapType
        var demoTypeOptions = {
          getTileUrl: mapTypeGetTileUrl,
          tileSize: new google.maps.Size(256, 256),
          isPng: true,
          maxZoom: 5,     // range of
          minZoom: 1,     // zoom levels
          name: "Demo"    // label for mapTypeControl if displayed
        };
        
        // Creating the ImageMapType object
        var demoMapType = new google.maps.ImageMapType(demoTypeOptions);
        // Adding "demo" to the mapTypes register
        map.mapTypes.set('demo', demoMapType);
        // Activating the "demo" MapType
        map.setMapTypeId('demo');
      }
      
      
      /**
       *  Builds url for background
       */
      function mapTypeGetTileUrl( coord, zoom ) {
        var backgroundPath = "img/bg";    // path to the background folder
        
        // Finding out if map is out of boundaries and if backgrounds should be repeated.
        // If not no background url is returned.
        var normalizedCoord = mapTypeGetNormalizedCoord(coord, zoom);
        if (!normalizedCoord) {
          return false;
        }
        
        // Calculating coordinates and return background url
        var bound = Math.pow(2, zoom);
        var xCoord = normalizedCoord.x;
        var yCoord = (bound - normalizedCoord.y - 1);
        return backgroundPath + "/" + zoom + "/" + xCoord + "/" + yCoord + ".png";
      }
      
      
      /**
       *  Normalizes the coords that tiles repeat across the x axis (horizontally)
       *  like the standard Google map tiles.
       */
      function mapTypeGetNormalizedCoord( coord, zoom ) {
        var y = coord.y;
        var x = coord.x;
      
        // tile range in one direction range is dependent on zoom level
        // 0 = 1 tile, 1 = 2 tiles, 2 = 4 tiles, 3 = 8 tiles, etc
        var tileRange = 1 &lt;&lt; zoom;
        
        // don't repeat across y-axis
        if (y < 0 || y >= tileRange)
          return null;                                  
        
        // repeat across x-axis
        if (x < 0 || x >= tileRange)
          x = (x % tileRange + tileRange) % tileRange;  
      
        return { x: x, y: y };
      }
    
    $(document).ready(function () {
      mapInit();
      mapTypeInit(); 
    });

      
      </pre>
    </div>
    <div class="section">
      <ul>
        <li>Add a function that adds an event listener to  the map on click and returns LatLng-coordinates of the cursor and the map  center</li>
        <li>Changing the draggableCursor option of your map  to &ldquo;crosshair&rdquo; makes it easier to hit a specific point</li>
        <li>The Firefox plug-in MeasureIt can help to get  bounds of objects on the backgrounds that aren&rsquo;t rectangular</li>
      </ul>
      <pre class="brush: js">
      	/**
         *  Add GMaps specific event listeners
         */
        function eventListenersInit(){
          }); 
          google.maps.event.addListener(map, 'click', function(event) {
            alert("cursor: " + event.latLng 
               + " center: " + map.getCenter());
          });
        }
        
        $(document).ready(function () {
          mapInit();
          mapTypeInit();
          eventListenersInit();
          map.setOptions({
            draggableCursor: "crosshair",
            draggingCursor: "crosshair"
          });
        });
      </pre>
    </div>
  </div>
  <div id="content-3" class="content">
    <ul class="headlines">
      <li class="summary"><a href="#">Summary</a></li>
      <li><a href="#">Create <br />mark-up</a></li>
      <li><a href="#">Integrate into <br />GMaps' controls</a></li>
      <li><a href="#">Add <br />events</a></li>
    </ul>
    <div class="section summary">
      <ul>
        <li>Create mark-up for the controls, e.g. a navigation</li>
        <li>GMaps has a control grid in which you can integrate controls at certain positions</li>
        <li>Actions like moving to a position  or changing the zoom level can all be added with jQuery</li>
      </ul>
    </div>
    <div class="section">
      <ul>
        <li>Add your control to the &lt;body&gt; tag as  usual</li>
        <li>Don&rsquo;t worry about z-index or positioning, GMaps  is taking care of all that</li>
      </ul>
      <pre class="brush: xml">
      	&lt;div id=&quot;header&quot;&gt;
          &lt;div class=&quot;headline&quot;&gt;img src=&quot;img/slogan.png&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;
          &lt;div id=&quot;navigation&quot;&gt;
            &lt;ul&gt;
              &lt;li&gt;&lt;a href=&quot;#&quot; class=&quot;active&quot;&gt;
                &lt;div class=&quot;icon link-0&quot;&gt;&lt;/div&gt;&lt;p&gt;Start&lt;br /&gt;presentation&lt;/p&gt;&lt;/a&gt;&lt;/li&gt;
              &lt;li&gt;&lt;a href=&quot;#&quot;&gt;
                &lt;div class=&quot;icon link-1&quot;&gt;&lt;/div&gt;&lt;p&gt;Create&lt;br /&gt;background&lt;/p&gt;&lt;/a&gt;&lt;/li&gt;
              &lt;li&gt;&lt;a href=&quot;#&quot;&gt;
                &lt;div class=&quot;icon link-2&quot;&gt;&lt;/div&gt;&lt;p&gt;Assign background&lt;br /&gt;to GMaps&lt;/p&gt;&lt;/a&gt;&lt;/li&gt;
              &lt;li&gt;&lt;a href=&quot;#&quot;&gt;
                &lt;div class=&quot;icon link-3&quot;&gt;&lt;/div&gt;&lt;p&gt;Add&lt;br /&gt;controls&lt;/p&gt;&lt;/a&gt;&lt;/li&gt;
              &lt;li&gt;&lt;a href=&quot;#&quot;&gt;
                &lt;div class=&quot;icon link-4&quot;&gt;&lt;/div&gt;&lt;p&gt;Add markers&lt;br /&gt;and overlays&lt;/p&gt;&lt;/a&gt;&lt;/li&gt;
              &lt;li&gt;&lt;a href=&quot;#&quot;&gt;
                &lt;div class=&quot;icon link-5&quot;&gt;&lt;/div&gt;&lt;p&gt;Add and&lt;br /&gt;style windows&lt;/p&gt;&lt;/a&gt;&lt;/li&gt;
            &lt;/ul&gt;
          &lt;/div&gt;
      	&lt;/div&gt;
      </pre>
    </div>
    <div class="section">
      <pre class="brush: js">
        function navigationInit(){
          // Integrating the header into Google Maps' control grid
          var header = $("#header")[0];
          map.controls[google.maps.ControlPosition.TOP_CENTER].push(header);
        }
        $(document).ready(function() { 
          startCenter = new google.maps.LatLng(-60.86391376572419, -18.652343749999996);  
          mapInit();
          mapTypeInit();
          navigationInit();
        });
      </pre>
    </div>
    <div class="section">
      <ul>
        <li>Add the global variable &lsquo;content&rsquo;</li>
        <li>In this case you can use a jQuery click event</li>
        <li>Add a function (&lsquo;navigationHighlight&rsquo;) to always  highlight the active navigation element</li>
        <li>Set up an object (&lsquo;content&rsquo;) that holds  information about positions and later clickable areas and references to content  in the DOM</li>
      </ul>
      <pre class="brush: js">
      	var map, startCenter, content;
        ...
        function navigationInit(){
          ...
          // Adding click event to links
          $("#navigation").find(" ul li a").each(function(i){
            $(this).click(function(event){
              event.preventDefault();
              
              // Getting index of the link
              var index = $("#navigation").find(" ul li a").index($(this));
              
              // Moving to startCenter if first element was clicked
              // else opening the InfoBox matching to index
              if (index == 0){
                map.setZoom(2);
                setTimeout(function(){ map.panTo(startCenter); }, 250);
              }
              else {
                map.setZoom(4);
                // index of content starts at 0 but in navigation chapters start at 1
                setTimeout(function(){ map.panTo(content[index-1].position); }, 250);
              }      
              // Assign active status/class to the clicked link
              navigationHighlight(index);
            });      
          });
        }
        function navigationHighlight(index){
          var links = $("#navigation").find(" ul li a");
          // Removing all highlights
          links.removeClass("active");
          // If index is negative no element gets highlighted
          if (index >= 0)
            links.eq(index).addClass("active");
        }
        
        $(document).ready(function() {
          content = [
            { position: new google.maps.LatLng(-75.927, -117.059) },
            { position: new google.maps.LatLng(-54.348, -38.536) },
            { position: new google.maps.LatLng(-78.335, 19.0972) },
            { position: new google.maps.LatLng(-47.677, 77.131) },
            { position: new google.maps.LatLng(-76.475, 125.997) }
          ]; 
          ...
          navigationInit();
        });

      </pre>
    </div>
  </div>
  <div id="content-4" class="content">
    <ul class="headlines">
      <li class="summary"><a href="#">Summary</a></li>
      <li><a href="#">What's the <br />difference</a></li>
      <li><a href="#">Create <br />markers</a></li>
      <li><a href="#">Create <br />overlays</a></li>
    </ul>
    <div class="section summary">
      <ul>
        <li>A marker's position is defined by one point on the map and it has a fixed pixel size</li>
        <li>A ground overlay is defined by two coordinates (SW,NE) and therefore its size depends on the zoom level</li>
        <li>Both can show custom images</li>
      </ul>
    </div>
    <div class="section">
      <ul>
        <li>A marker&rsquo;s position is defined by one point on  the map and it has a fixed size, so whatever zoom level is loaded the marker  has the same pixel size</li>
        <li>A ground overlay is defined by two coordinates  (SW,NE) and therefore its size depends on the zoom level</li>
        <li>So if you want an area on your background to be  clickable you should use a ground overlay</li>
        <li>Use the global &lsquo;content&rsquo; object to store  positioning information if the overlays are related to the content</li>
      </ul>
      <pre class="brush: js">
        $(document).ready(function() { 
          content = [
            {
              position: new google.maps.LatLng(-76, -116.5),
              markerPos: new google.maps.LatLng(-82.28, -117),
              overlayBounds: new google.maps.LatLngBounds(
                new google.maps.LatLng(-77.967, -126.143),
                new google.maps.LatLng(-73.552, -107.993))
            },
            {
              position: new google.maps.LatLng(-54.5, -38.25),
              markerPos: new google.maps.LatLng(-54.5, -76.28),
              overlayBounds: new google.maps.LatLngBounds(
                new google.maps.LatLng(-59.286, -47.656),
                new google.maps.LatLng(-48.717, -29.507))
            },
            {
              position: new google.maps.LatLng(-78.4, 19.3),
              markerPos: new google.maps.LatLng(-83.4, -0.95),
              overlayBounds: new google.maps.LatLngBounds(
                new google.maps.LatLng(-80.034, 10),
                new google.maps.LatLng(-76.340, 28.193))
            },
            {
              position: new google.maps.LatLng(-47.9, 77.4),
              markerPos: new google.maps.LatLng(-20.17, 88.65),
              overlayBounds: new google.maps.LatLngBounds(
                new google.maps.LatLng(-53.407, 68.096),
                new google.maps.LatLng(-41.208, 86.201))
            },
            {
              position: new google.maps.LatLng(-76.5, 126.6),
              markerPos: new google.maps.LatLng(-73.5, 161.94),
              overlayBounds: new google.maps.LatLngBounds(
                new google.maps.LatLng(-78.437, 116.875),
                new google.maps.LatLng(-74.187, 135.068))
            }
          ];
        
          ...
        });  
      </pre>
    </div>
    <div class="section">
      <ul>
        <li>A marker needs a position, an image and a map</li>
        <li>For more exact positioning an anchor point can  be set</li>
      </ul>
      <pre class="brush: js">
        function overlaysInit(){
          // Creating an options object for the marker images
          var mImgOptions = {
            // This marker is 32 pixels wide & tall.
            width: new google.maps.Size(32, 32),
            // The origin for this image is 0,0.  
            origin: new google.maps.Point(0,0),
            // The anchor is the center of the circle 16,16. 
            anchor: new google.maps.Point(16, 16)
          };
          for (var i = 0; i < content.length; i++){
            // Creating the marker images for normal and hover state
            content[i].mImage = new google.maps.MarkerImage("img/c"+i+".png",
              mImgOptions.width, mImgOptions.origin, mImgOptions.anchor);
            content[i].mHoverImage = new google.maps.MarkerImage("img/c"+i+"-hover.png",
              mImgOptions.width, mImgOptions.origin, mImgOptions.anchor);
            
            // Creating the actual marker
            // it appears as soon as it has a map defined
            content[i].marker = new google.maps.Marker({
              position: content[i].markerPos,
              icon: content[i].mImage,
              map: map,
              zIndex: i
            });
            
            // Adding hover and click events
            google.maps.event.addListener(content[i].marker, 'mouseover', overlaysMarkerHover);
            google.maps.event.addListener(content[i].marker, 'mouseout', overlaysMarkerHover);
            google.maps.event.addListener(content[i].marker, 'click', function(event){
              // Zooming out and center map
              map.setZoom(2);
              setTimeout(function(){ map.panTo(startCenter); }, 250);
            });
          }
        }
        
        /**
         *  Changes marker image on mouseover and mouseout
         */  
        function overlaysMarkerHover(event) {
          var index = this.getZIndex();
          var image = event.type == "mouseover" ?
            content[index].mHoverImage : content[index].mImage;
          this.setIcon(image);
        }
        
        $(document).ready(function() { 
          ...
          overlaysInit();
        });
      </pre>
    </div>
    <div class="section">
      <ul>
        <li>The transparent overlay only needs it&rsquo;s bounds  and a map</li>
      </ul>
      <pre class="brush: js">
        function overlaysInit(){
          ...
          for (var i = 0; i < content.length; i++){
            ...      
            // Creates transparent overlay
            content[i].overlay = new google.maps.GroundOverlay(
              null, content[i].overlayBounds, { map: map });
          }
        }
      </pre>
    </div>
  </div>
  <div id="content-5" class="content">
    <ul class="headlines">
      <li class="summary"><a href="#">Summary</a></li>
      <li><a href="#">Create window<br />with InfoBox</a></li>
      <li><a href="#">Add control<br />events</a></li>
      <li><a href="#">Conclusion</a></li>
    </ul>
    <div class="section summary">
      <ul>
        <li>The default info window can not be styled</li>
        <li>The plug-in InfoBox of the GMaps Utility Library works the same and can be styled</li>
        <li>Any kind of content can be loaded from the DOM or via AJAX</li>
      </ul>
    </div>
    <div class="section">
      <ul>
        <li>Download and load the InfoBox plug-in which is  based on the default InfoWindow but is completely styleable. It is part of  Google Maps Utility Library V3 (<a href="http://code.google.com/p/google-maps-utility-library-v3/wiki/Libraries">http://code.google.com/p/google-maps-utility-library-v3/wiki/Libraries</a>)</li>
        <li>Add content to DOM</li>
        <li>Add references to DOM-elements in content object</li>
        <li>Create functions for creating, opening and  closing infoBoxes</li>
        <li>create infoBoxes in overlaysInit</li>
      </ul>
      <pre class="brush: xml">
        &lt;script type=&quot;text/javascript&quot;  src=&quot;js/infobox_packed.js&quot;&gt;&lt;/script&gt;
      </pre>
      <pre class="brush: xml">
        &lt;div id=&quot;content&quot;&gt;
          &lt;div id=&quot;content-1&quot; class=&quot;content&quot;&gt;
            &lt;ul class=&quot;headlines&quot;&gt;
              &lt;li&gt;&lt;a href=&quot;#&quot;&gt;About&lt;br /&gt;
                the file&lt;/a&gt;&lt;/li&gt;
              &lt;li&gt;&lt;a href=&quot;#&quot;&gt;Tile background&lt;br /&gt;
                with MapTiler&lt;/a&gt;&lt;/li&gt;
              &lt;li&gt;&lt;a href=&quot;#&quot;&gt;Tip: Varying&lt;br /&gt;
                backgrounds&lt;/a&gt;&lt;/li&gt;
            &lt;/ul&gt;
            &lt;div class=&quot;section&quot;&gt;
              ...
            &lt;div class=&quot;section&quot;&gt;
              ...
            &lt;div class=&quot;section&quot;&gt;
              ...
            &lt;/div&gt;
          &lt;/div&gt;
        &lt;/div&gt;
  		</pre>
      <pre class="brush: js">
        content = [
          {
            container: $("#content-1"),
            position: new google.maps.LatLng(-76, -116.5),
            markerPos: new google.maps.LatLng(-82.28, -117),
            overlayBounds: new google.maps.LatLngBounds(
              new google.maps.LatLng(-77.967, -126.143),
              new google.maps.LatLng(-73.552, -107.993))
          },
          {
            container: $("#content-2"),
            ...
          },
          ...
        ];
      </pre>
      <pre class="brush: js">
        /**
         * Creates InfoBox
         */
        function infoBoxCreate( index ){
          // Loading the matching chapter & position from the content object
          var myOptions = {
               content: content[index].container[0]
              ,position: content[index].position
              ,alignBottom: true
              ,pixelOffset: new google.maps.Size(-300, 0)
              ,infoBoxClearance: new google.maps.Size(50, 110)
              ,closeBoxMargin: "19px 5px 0"
              ,closeBoxURL: "img/close.png"
              ,maxWidth: 0
          };
          var infoBox = new InfoBox(myOptions);
          
          // Handling clicks on overlays
          google.maps.event.addListener(content[index].overlay, 'click', function(event){
            openInfoBox(index);
            navigationHighlight(index+1);
          });
          // Handling clicks on close button
          google.maps.event.addListener(infoBox, 'closeclick', function(event){
            navigationHighlight(-1); // Deactivate navigation element
          });
        
          return infoBox;
        }
        
        /**
         * Open a specific InfoBox
         */
        function openInfoBox( index ){
          // Closing all InfoBoxes
          for (var i = 0; i < content.length; i++){
            content[i].infoBox.close();    
          }
          // Opening the InfoBox
          if (index >= 0){
            map.setZoom(4);
            // Delay the opening because zoom and panTo at the same time can cause problems
            setTimeout(function(){ content[index].infoBox.open(map) }, 250);
          }
        }
        
        /**
         * Closes InfoBoxes and deactivates navigation elements
         */
        function closeInfoBoxes(){
            navigationHighlight(-1);
            openInfoBox(-1);
        }
        
        function overlaysInit(){
          ...
            // Creates the InfoBox
            content[i].infoBox = infoBoxCreate(i);
          }
        }
      </pre>
    </div>
    <div class="section">
      <ul>
        <li>Edit click event on navigation elements to call  &lsquo;openInfoBox&rsquo;</li>
        <li>Close InfoBoxes on click on map and when zoom  level changes</li>
        <li>Add Tab function for infoBoxes</li>
      </ul>
      <pre class="brush: js">
      	function navigationInit(){
          ...
          $("#navigation").find(" ul li a").each(function(i){
            $(this).click(function(event){
              ...
              if (index == 0){
                ...
              }
              else {
                // index of content starts at 0 but in navigation chapters start at 1
                openInfoBox(index-1);
              }
              ...
            });      
          });
        }
        
        function overlaysInit(){
          ...  
          // Closes InfoBoxes on click on map and when zoom level changes
          google.maps.event.addListener(map, 'zoom_changed', closeInfoBoxes); 
          google.maps.event.addListener(map, 'click', closeInfoBoxes);
        }
        
        /**
         * Adds a tab function to the content sections
         * of each InfoBox
         */
        function contentTabs(){
          // Applying to all .content elements
          $("#content .content").each(function(i){
            var thisContent   = $(this);
            var headlineLinks = $(this).find(" .headlines a");
            var sections      = $(this).find(" .section");
            
            sections.hide();
            
            // Adding click event to all links in .headlines
            headlineLinks.each(function(a){
              $(this).click(function(event){
                event.preventDefault();
                
                // Managing active navigation element
                headlineLinks.removeClass("active");
                $(this).addClass("active");
                
                // Managing visible content element
                sections.hide();
                var index = headlineLinks.index($(this));
                sections.eq(index).slideDown('fast');
              })
              headlineLinks.first().click();
            })
          });
        }
        $(document).ready(function() {
          content = [
            ...
          ];
        
          ...
        });
      </pre>
    </div>
    <div class="section summary">
      <h1>How far can this go?</h1>
      <ul>
        <li>Using different backgrounds on each level can be used for amazing things</li>
        <li>Markers, overlays and info boxes can be limited to zoom levels too</li>
        <li>Info boxes can also be used as overlays fixed to a position on map</li>
        <li>The content of info boxes can be everything imaginable</li>
        <li>Much further than I can think of...</li>
      </ul>
      <h1>Sources</h1>
      <ul>
      	<li><a href="http://code.google.com/apis/maps/documentation/javascript/">
      	  http://code.google.com/apis/maps/documentation/javascript/
      	</a></li>
      	<li><a href="http://code.google.com/p/google-maps-utility-library-v3/wiki/Libraries">
      	  http://code.google.com/p/google-maps-utility-library-v3/wiki/Libraries
      	</a></li>
      	<li><a href="http://jquery.com">
      	  http://jquery.com
      	</a></li>
      	<li><a href="http://maptiler.org">
      	  http://maptiler.org
      	</a></li>
      	<li><a href="http://alexgorbatchev.com/SyntaxHighlighter/">
      	  http://alexgorbatchev.com/SyntaxHighlighter/
      	</a></li>
      	<li><a href="http://jscrollpane.kelvinluck.com/">
      	  http://jscrollpane.kelvinluck.com/
      	</a></li>
      </ul>
    </div>
  </div>
</div>

<script type="text/javascript" src="http://maps.google.com/maps/api/js?v=3.3&sensor=false"></script>
<script type="text/javascript" src="js/infobox_packed.js"></script>

<script type="text/javascript" src="js/jquery-1.6.2.min.js"></script>

<script src="js/jquery.mousewheel.js" type="text/javascript"></script>
<script src="js/jquery.jscrollpane.js" type="text/javascript"></script>


<script type="text/javascript" src="js/shCore.js"></script>
<script type="text/javascript" src="js/shBrushJScript.js"></script>
<script type="text/javascript" src="js/shBrushXml.js"></script>
  
<script type="text/javascript" src="js/scripts.js"></script>
</body>
</html>